<template>
  <div class="container">
    <p style="position: absolute; left: 0; top: 0">{{ fps }}</p>
    <div class="myCanvas" ref="canvasRef"></div>
  </div>
</template>

<script setup lang="ts">
import { useFps } from '@vueuse/core'
import Konva from 'konva'
import { Layer } from 'konva/lib/Layer'
import { Circle } from 'konva/lib/shapes/Circle'
import { Stage } from 'konva/lib/Stage'
import { onMounted, reactive, ref } from 'vue'
Konva.autoDrawEnabled = false

const fps = useFps()
const canvasRef = ref()
const canvasSize = reactive({
  width: 100,
  height: 200,
})
const setCanvasSize = () => {
  const width = canvasRef.value?.offsetWidth || document.body.offsetWidth
  const height = canvasRef.value?.offsetHeight || document.body.offsetHeight
  canvasSize.width = width
  canvasSize.height = height
}

const circle = new Konva.Circle({
  x: 0,
  y: 0,
  radius: 5,
  fill: 'red',
  listening: false,
})
circle.cache()

const circles: Circle[] = []
const drawCircle = (count: number) => {
  const rects = Array.from(new Array(count)).map(() => {
    return {
      x: Math.random() * canvasSize.width,
      y: Math.random() * canvasSize.height,
    }
  })
  if (!circles.length) {
    for (let i = 0; i < rects.length; i++) {
      const centerX = rects[i].x
      const centerY = rects[i].y
      const newCircle = circle.clone({
        x: centerX,
        y: centerY,
      })
      circles.push(newCircle)
      layer?.add(newCircle)
    }
  } else {
    for (let i = 0; i < rects.length; i++) {
      const centerX = rects[i].x
      const centerY = rects[i].y
      const curCircle = circles[i]
      curCircle.x(centerX)
      curCircle.y(centerY)
    }
  }
  layer?.batchDraw()
}

let stage: Stage | null = null
let layer: Layer | null = null
const init = () => {
  stage = new Konva.Stage({
    container: canvasRef.value,
    width: canvasSize.width,
    height: canvasSize.height,
  })
  layer = new Konva.FastLayer({
    listening: false,
  })
  stage.add(layer)
  const drawFrame = () => {
    drawCircle(20000)
    window.requestAnimationFrame(drawFrame)
  }
  window.requestAnimationFrame(drawFrame)
}
onMounted(() => {
  setCanvasSize()
  init()
})
</script>

<style scoped lang="scss">
.container {
  width: 100%;
  height: calc(100vh - 60px - 50px - 40px);

  .myCanvas {
    width: 100%;
    height: 100%;
  }
}
</style>
